fld = flsys:NewModule("fld", "AceConsole-3.0", "AceEvent-3.0")

--VARIABLES
local lootTable = {}
local lootCache = {}
local lootcount = 0
local lootdone = 0
local lootmob = ""
local roster = {} --k=name,v={rollsdone, row}
local size = 0
local rollingopen = false
local rollsrec = 0
local progressframebuttons = {}
local lootlistbuttons = {[1]="blank"}

local QUEST_ITEMS = {
	[77952] = true, --elementium gem cluster (dragon soul)
	[71141] = true, --eternal ember (firelands)
}

local rollorder = {
	["m"] = 0, --masterlooter assigned
	["n"] = 1,
	["s"] = 2,
	["o"] = 3,
	["g"] = 4,
	["z"] = 5, --sell/shard
	["p"] = 6,
	["u"] = 7,
}

local defaults = {
    profile = {
		autoassign = {},
		rarity_threshold = 3,
		sharder = "",
		seller = "",
		boeopts = "np",
		emberopts = "np",
		defaultopts = "nsop"
	},
}

function fld:GetAutoAssign()
    local autostr = ""
	for k, v in pairs(self.db.profile.autoassign) do
		autostr = autostr..(string.format("%s assigned to %s\n", k, v))
    end
    return autostr
end

--INITIALIZE/ENABLE FUNCS
function fld:OnEnable()
	self.db = LibStub("AceDB-3.0"):New("FlamingLootSysDB", defaults)
	RegisterAddonMessagePrefix("flamingloot")
	self:RegisterEvent("CHAT_MSG_ADDON")
	self:RegisterChatCommand("loot", "AccessCache")
end

--START
function fld:StartRaid() --called by flsys
	self:RegisterEvent("LOOT_OPENED")
	fld:CreateRoster()
	if fld.db.profile.promptz and not roster[self.db.profile.sharder] then
		fld:CheckSharder()
	end
	self:RegisterEvent("CHAT_MSG_WHISPER")
	if fld.db.profile.whispopts then
		flsys:Print("Announcing roll options for people without the addon is enabled.  Open the options menu to disable.")
	else
		flsys:Print("Announcing roll options for people without the addon is disabled.  Open the options menu to enable.")
	end
end

function fld:CreateRoster()
	wipe(roster)
	size = GetNumRaidMembers()
	for i=1, GetNumRaidMembers() do
		local name = select(1, GetRaidRosterInfo(i))
		roster[name] = {["rollsdone"] = 0}
	end
	fld:InitializeFrames()
end

function fld:InitializeFrames()
	--progress frame
	FLProgressFrame:SetScale(.8)
	FLProgressFrameTitle:SetText("Progress")
	for i=1, size do
		if not progressframebuttons[i] then
			local row = fld:CreateTableRow({"", ""})
			row:SetPoint("TOPLEFT", FLProgressFrame, 10, -15-16*i)
			table.insert(progressframebuttons, row)
		end
	end
	FLProgressFrame:SetSize(120, 70+size*17)
	local count = 0
	for name, _ in pairs(roster) do --assigns rows, so they can be reused when we re-make the roster
		count = count+1
		progressframebuttons[count].cells[1]:SetText(name)
		roster[name]["row"] = count
	end
	--awarding frame
	FLAwardFrame:SetScale(.8)
	FLAwardFrameTitleText:SetText("Award loot")
	FLAwardFrame:SetHeight(50+lootcount*40)
	FLAwardFrame:SetScript("OnHide", function(self) fld:HideRollersList() end)
	FLAwardFrameCloseButton:SetScript("OnClick", function() fld:EndAwardingClicked() end)
	
	--rollers list
	FLRollersList:SetHitRectInsets(-10, 10, 10, -10)
end

function fld:CreateTableRow(texttable)
	local widths = {80, 20}
	local row = CreateFrame("Button", nil, FLProgressFrame)
	row:SetSize(100,16)
	row.cells = {}
	for i,w in ipairs(widths) do
		local c = row:CreateFontString(nil, "ARTWORK", "GameFontWhite")
		c:SetJustifyH("LEFT")
		c:SetWidth(w)
		if #row.cells == 0 then
			c:SetPoint("LEFT", row, "LEFT", 0, 0)
		else
			c:SetPoint("LEFT", row.cells[#row.cells], "RIGHT", 0, 0)
		end
		c:SetText(texttable[i])
		table.insert(row.cells, c)
	end
	return row
end

--LOOT
function fld:LOOT_OPENED()
	flsys:debug(1, "LOOT_OPENED")
	if lootTable[1] and lootTable[1].link then --already opened loot
		flsys:Print("The loot table is not empty - awarding not ended.  Not announcing loot.")
		flsys:debug(1, "LOOT", "not empty - awarding not ended.  not announcing loot.")
		fld:RefreshIndices()
	else
		for i=1, GetNumLootItems() do
			--checks
			if LootSlotIsItem(i) then
				local itemlink = GetLootSlotLink(i)
				flsys:debug(2, "Loot opened GetLootSlotLink(i) = "..itemlink)
				local rarity = select(3, GetItemInfo(itemlink))
				if rarity >= self.db.profile.rarity_threshold then
					--passed checks, check announce
					StaticPopup_Show("STARTLOOTING")	
				else
					flsys:debug(2, "Didn't pass rarity check")
				end
			end
		end
	end
end

function fld:GetLootInfo()
	local announcemsg = (UnitName("target") or "Loot chest")..": "
	local announcepos = 1
	wipe(lootCache)
	for i=1, GetNumLootItems() do
		if LootSlotIsItem(i) then
			local itemlink = GetLootSlotLink(i)
			local itemname, _, rarity, iLevel, _, class, subtype, _, equipLoc, texture, _ = GetItemInfo(itemlink)
			subtype = subtype or "no subtype"
			if rarity >= self.db.profile.rarity_threshold then
				local first = fld:FindCopy(itemlink)
				if first then --same item already in loot table
					lootTable[first].quant = lootTable[first].quant + 1
					lootTable[first]["index"..lootTable[first].quant] = i
					announcemsg = announcemsg..itemlink.." "
				else
					lootcount = lootcount + 1
					if not lootTable[lootcount] then
						lootTable[lootcount] = {["rolls"]={}, ["needcount"]=0, ["texture"] = texture, ["subs"] = {}}
						fld:CreateAwardFrameSection(lootcount)
					end
					lootTable[lootcount].itemid = fld:LinktoID(itemlink)
					lootTable[lootcount].name = itemname
					lootTable[lootcount].equipLoc = equipLoc
					lootTable[lootcount].link = itemlink
					lootTable[lootcount].texture = texture
					lootTable[lootcount].ilvl = iLevel
					lootTable[lootcount].index1 = i
					lootTable[lootcount].quant = 1
					lootTable[lootcount].prog = 1
					lootCache[lootcount] = {["link"] = itemlink, ["rolls"] = {}} --cache				
					fld:TypeChecks(lootcount, itemname, itemlink, class, subtype)
					announcemsg = announcemsg..itemlink.." "
					if fld.db.profile.whispopts and lootTable[lootcount].rollopts then
						announcemsg = announcemsg.."("..lootTable[lootcount].rollopts..") "
					end
				end
				SendChatMessage(string.sub(announcemsg, announcepos, -1), "RAID", nil)
				announcepos = string.len(announcemsg)
			end
		end
	end
	fld:StartLooting()
end
					
function fld:RefreshIndices()
	flsys:debug(2, "Looting", "Refreshing indices")
	for pos, item in ipairs(lootTable) do
		local copies = 1
		for i=1, GetNumLootItems() do --refresh indices since they might have changed
			if LootSlotIsItem(i) then
				local linky = GetLootSlotLink(i)
				if linky==lootTable[pos].link then
					lootTable[pos]["index"..copies] = i
					copies = copies +1
				end
			end
		end
	end
end

function fld:TypeChecks(lootcount, itemname, itemlink, class, subtype)
	self:Print("Type checks "..itemlink..class..subtype)
	if self.db.profile.autoassign[itemname] and roster[self.db.profile.autoassign[itemname]] then --auto-assign & player is in group
		table.insert(lootTable[lootcount].rolls, {["player"] = self.db.profile.autoassign[itemname], ["rolltype"] = "m", ["rollstr"] = "auto-assigned to "..self.db.profile.autoassign[itemname], ["roll"] = 0})
		rollsrec = rollsrec+size --for progress purposes, say everyone rolled on it
	else
		if fld:IsBoE(itemlink) then --boe gear
			if self.db.profile.boeopts then
				lootTable[lootcount].rollopts = self.db.profile.boeopts
			end
			lootTable[lootcount].passtype = "sell"
		elseif class==("Weapon" or "Armor") then --bop gear
			lootTable[lootcount].rollopts = self.db.profile.defaultopts
			lootTable[lootcount].passtype = "disenchant"
		elseif class=="Trade Goods" then --living ember/essence
			if self.db.profile.emberopts then
				lootTable[lootcount].rollopts = self.db.profile.emberopts
			end
			lootTable[lootcount].passtype = "sell"
		elseif class=="Recipe" then --recipe
			lootTable[lootcount].rollopts = "gp"
			lootTable[lootcount].passtype = "sell"
		elseif fld:IsMount(itemlink) then --mount
			lootTable[lootcount].rollopts = "gp"
		elseif QUEST_ITEMS[lootTable[lootcount].itemid] then --quest item, can't sell or de
			lootTable[lootcount].rollopts = "nop"
		else
			if subtype=="Junk" then --token
				lootTable[lootcount].passtype="sell"
			end
			lootTable[lootcount].rollopts = self.db.profile.defaultopts --just in case
		end
	end
end

function fld:FindCopy(itemlink)
	for i, t in ipairs(lootTable) do
		if lootTable[i].link == itemlink then
			flsys:debug(2, "Looting", "Found a copy! "..itemlink)
			return i
		end
	end
	return nil
end

function fld:StartLooting()
	rollingopen=true
	local sendmsg = "loot:" 
	local count = 0
	for pos=1, lootcount do
		if not lootTable[pos].rolls[1] and lootTable[pos].rollopts then
			sendmsg = sendmsg..lootTable[pos].itemid.."="..lootTable[pos].rollopts..";"
			count=count+1
		end
	end
	SendAddonMessage("flamingloot", sendmsg, "RAID")
	flsys:debug(1, "sending: "..sendmsg)
	fld:ShowProgressFrame(count)
end

function fld:AccessCache(input)
	local printstr = ""
	if not input or input:trim() == "" then
		if lootCache[1] then
			printstr = lootCache.prefix
			for i, t in ipairs(lootCache) do
				if lootCache[i].link then
					printstr = printstr..i..". "..lootCache[i].link.." "
				end
			end
			flsys:Print(printstr.."\n Type /loot [number] to view rolls for that item.")
		else
			printstr = "No loot cached."
		end
	elseif string.match(input, "%d") then
		local num = tonumber(string.match(input, "(%d)"))
		if lootCache[num].link then
			if lootCache[num].rolls[1] then
				printstr = "Rolls for "..lootCache[num].link..":\n"
				for i, s in ipairs(lootCache[num].rolls) do
					printstr = printstr..i..". "..lootCache[num].rolls[i].."\n"
				end
			else
				printstr = "No rolls stored for "..lootCache[num].link
			end
		else
			printstr = "There is no cached item under that number"
		end
		flsys:Print(printstr)
	end
end

--ROLLING
function fld:ShowProgressFrame(count)
	FLProgressFrameTitle:SetText(count.." items")
	for player,v in pairs(roster) do
		fld:UpdateProgressFrame(player)
	end
	FLProgressFrame:Show()
end

function fld:UpdateProgressFrame(player)
	if roster[player].rollsdone==lootcount then
		progressframebuttons[roster[player].row].cells[2]:SetText("|cff98e0ff"..roster[player].rollsdone)
		progressframebuttons[roster[player].row].cells[1]:SetText("|cff98e0ff"..player)
	else
		progressframebuttons[roster[player].row].cells[1]:SetText(player)
		progressframebuttons[roster[player].row].cells[2]:SetText(roster[player].rollsdone)
	end
end

function fld:RollReceived(sender, message, whisp)
	--message format: "itemid=rolltype;roll#"
	local itemid, rolltype, roll = string.match(message, "(%d+)=(%a+);*(%d*)")
	roll = tonumber(roll) or 0
	itemid = tonumber(itemid)
	for i, itable in pairs(lootTable) do
		local id = tonumber(itable.itemid)
		if id==itemid then
			pos = i 
			break
		end
	end
	if pos and (string.find(lootTable[pos].rollopts, rolltype) or rolltype=="u") then --valid roll type
		local stringconverter = {
			["n"] = "%s (need)", --player
			["p"] = "%s (pass)", --player
			["s"] = "%s (sidegrade, rolled %d)", --player, roll
			["g"] = "%s (greed, rolled %d)", --player, roll
			["o"] = "%s (offspec, rolled %d)", --player, roll
			["u"] = "%s (autopass)", --player
		}
		if whisp then
			SendChatMessage("Roll received"..string.format(stringconverter[rolltype], "", roll), "WHISPER", nil, sender)
		end
		if rolltype=="n" then
			if flsys.db.profile.mode==1 and not (self.db.profile.players[sender].temp and self.db.profile.players[sender].gp_total>0) then
				lootTable[pos].needcount = lootTable[pos].needcount+1
				if flsys.db.profile.players[sender].temp then
					table.insert(lootTable[pos].subs, sender)
					flsys:Print(sender.." inserted into sub table, "..#lootTable[pos].subs)
				end
			end
		end
		table.insert(lootTable[pos].rolls, {["player"] = sender, ["rolltype"] = rolltype, ["roll"] = roll, ["rollstr"] = string.format(stringconverter[rolltype], sender, roll)})
		flsys:debug(3, "Roll received: "..sender..", "..rolltype..roll)
		roster[sender].rollsdone = roster[sender].rollsdone + 1 --for tracking progress
		fld:UpdateProgressFrame(sender)
		rollsrec = rollsrec + 1
	elseif whisp then
		SendChatMessage("Invalid roll! Follow the format '[itemlink] n' where n is your selection.  Make sure you linked the correct item and selected one of its available roll options.", "WHISPER", nil, sender)
	end
	if rollsrec == size*lootcount then 
		fld:EndLooting()
	end
end

function fld:EndLooting()
	flsys:debug(3, "Ending looting")
	rollingopen = false
	SendAddonMessage("flamingloot", "end:", "RAID")	
	SendChatMessage("Rolling closed.", "RAID", nil)
	FLProgressFrame:Hide()
	fld:SortRolls()
	FLAwardFrame:Show()
end

function fld:CHAT_MSG_WHISPER(bl, message, sender)
	if not roster[sender] then
		self:Print("whisperer not on rosteR")
		return
	end
	if message=="addon" then
		SendChatMessage("Download flaming loot at curse.com/addons/wow/flaming or roll via whisper. Loot is announced in raid chat along with roll options. N=need, s=sidegrade (mainspec, same ilvl or lower), o=offspec, g=greed. Rolling opens as soon as loot has been linked.", "WHISPER", nil, sender)
		SendChatMessage("To roll, send me '[itemlink] n' where n is your selection (whole word or just the first letter).  You'll get a reply stating whether your roll was received.  If you are a sub, send 'sub' for an explanation of loot rules.", "WHISPER", nil, sender)
	elseif message=="sub" then
		SendChatMessage("Subs are welcome to roll on any item. Sidegrade, OS & greed are random rolls. For need, you're assigned a number & the addon does a random roll between 1 and the number of needs on the item. If the roll matches your number, you win the item; if not", "WHISPER", nil, sender)
		SendChatMessage("it goes to the person with the highest priority in our system. This gives you the same odds as an open roll. Once you have won a mainspec item you'll only be eligible for another one if no one else rolls need. Please whisper me if you have any questions!", "WHISPER", nil, sender)
	else
		local itemid, selec = string.match(message, "item:(%d+).+|h|r%s*(%a)")
		if itemid and selec then
			if rollingopen then
				local r = math.random(100)
				fld:RollReceived(sender, itemid.."="..selec..";"..r, true)
			else
				SendChatMessage("Rolling is not open.", "WHISPER", nil, sender)
			end				
		end
	end		
end

--SORT
function fld:SortRolls()
	flsys:UpdatePR()
	lootCache.prefix = "Loot from "..lootmob.." "..date("%H:%M")..":\n"
	for pos, itable in ipairs(lootTable) do
		if itable.link and itable.rollopts then --ignore empty
			if #itable.rolls>itable.quant then --only need to sort if #rolls > #items
				if itable.subroll and itable.rolls[1].rolltype=="m" and self.db.profile.players[itable.rolls[1].player].gp_total>0 then --sub won but now has GP
					itable.rolls[1].rolltype="n"
					flsys:Print(itable.rolls[1].player.." has won something; putting back at end of list for "..itable.link)
					table.remove (itable.subs, itable.subroll)
					itable.subroll = nil
					itable.subannounce=nil
					itable.needcount = itable.needcount - 1
				end
				if #itable.subs>0 and itable.needcount>itable.quant and not itable.subroll then --sub roll needed
					itable.subroll = math.random(itable.needcount)
					flsys:debug(2, "SUB", itable.link.." needers: "..itable.needcount..", subs: "..#itable.subs.." random roll of "..itable.subroll)
					itable["subannounce"] = string.format("%d people rolled need on %s.  Random roll was %d.", itable.needcount, itable.link, itable.subroll)
					flsys:Print(itable.subannounce)
					if itable.subs[itable.subroll] then
						fld:BumpSub(pos, itable.subs[itable.subroll])
					end 
				end
				table.sort(itable.rolls, function(rollA, rollB) return fld:SortIndivRolls(rollA, rollB) end)  --main sort
			end
			if itable.rolls[1] and (itable.rolls[1]["rolltype"] == "p" or itable.rolls[1]["rolltype"] == "u") then --pass is top -> sell or shard
				passtype = itable.passtype or ""
				self:Print("passtype"..passtype)
				self:Print("seller"..self.db.profile.seller)
				if passtype=="sell" and self.db.profile.seller~="" then
					table.insert(itable.rolls, 1, {["player"] = self.db.profile.seller, ["rolltype"] = "z", ["rollstr"] = " "..passtype})
				elseif passtype=="disenchant" and self.db.profile.sharder~="" then 
					table.insert(itable.rolls, 1, {["player"] = self.db.profile.sharder, ["rolltype"] = "z", ["rollstr"] = " "..passtype})
				end
			end
			--flsys:debug(1, "SORT", itable.rolls[1].." is winner, "..itable.rolls[1].rolltype)
			--cache rolls	
			for ii, _ in ipairs(itable.rolls) do
				lootCache[pos].rolls[ii] = itable.rolls[ii].rollstr
			end
		end
	end
	fld:UpdateAwardFrame()
end

function fld:BumpSub(pos, subname)
	for i, r in ipairs(lootTable[pos].rolls) do
		if r.player==subname then
			r.rolltype="m"
			flsys:Print(subname.." won the sub roll for "..lootTable[pos].link.."; bumping to top.")
		end
	end
end

function fld:SortIndivRolls(rollA, rollB)
	if rollA.rolltype ~= rollB.rolltype then 
		return rollorder[rollA.rolltype] < rollorder[rollB.rolltype]
	elseif rollA.rolltype == "n" and (flsys:GetPR(rollA.player)~=flsys:GetPR(rollB.player)) then
		return flsys:SortByPR(rollA.player, rollB.player)
	else
		return rollA.roll > rollB.roll
	end
end

--AWARD
function fld:CreateAwardFrameSection(i)
	lootTable[i]["itembutton"] = CreateFrame("Button", nil, FLAwardFrame)
	lootTable[i].itembutton:SetSize(30,30) 			
	lootTable[i].itembutton:SetPoint("TOPLEFT", FLAwardFrame, "TOPLEFT", 10, -30-(i-1)*40)
	lootTable[i].itembutton:SetNormalTexture(lootTable[i].texture)
	lootTable[i].itembutton:SetScript("OnEnter", function(self, motion) FlamingLoot:ShowTooltip(FLAwardFrame, lootTable[i].link, "ANCHOR_LEFT") end)
	lootTable[i].itembutton:SetScript("OnLeave", function(self, motion) GameTooltip:Hide() end)
	lootTable[i].itembutton:SetText(" ")
	local fontstr = lootTable[i].itembutton:GetFontString()
	fontstr:SetAllPoints(lootTable[i].itembutton)
	fontstr:SetFont("Fonts\\ARIALN.TTF", 10, "THICKOUTLINE")
	
	lootTable[i]["winnerbutton"] = CreateFrame("Button", nil, FLAwardFrame)
	lootTable[i].winnerbutton:SetSize(157, 30) 
	lootTable[i].winnerbutton:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")
	lootTable[i].winnerbutton:SetPoint("TOPLEFT", FLAwardFrame, "TOPLEFT", 43, -30-(i-1)*40)
	lootTable[i].winnerbutton:SetScript("OnEnter", function(self, motion) fld:ShowRollersList(i) end)
	lootTable[i].winnerbutton:SetNormalFontObject("GameFontWhiteSmall") 
	lootTable[i].winnerbutton:SetText("blank")
	fontstr = lootTable[i].winnerbutton:GetFontString()
	fontstr:SetAllPoints(lootTable[i].winnerbutton)
	--lootTable[i].winnerbutton:Show()
end

function fld:UpdateAwardFrame()		
	for pos=1, lootcount do
		if lootTable[pos].quant>=lootTable[pos].prog then
			lootTable[pos].itembutton:SetNormalTexture(lootTable[pos].texture)
			lootTable[pos].itembutton:SetScript("OnEnter", function(self, motion) FlamingLoot:ShowTooltip(FLAwardFrame, lootTable[pos].link, "ANCHOR_LEFT") end)
			lootTable[pos].winnerbutton:SetText(lootTable[pos].rolls[1].rollstr)  
			lootTable[pos].winnerbutton:SetScript("OnClick", function() fld:AwardPressed(pos, lootTable[pos].rolls[1].player, lootTable[pos].rolls[1].rolltype) end)
			lootTable[pos].winnerbutton:Show()
			lootTable[pos].itembutton:Show()
		end
		if lootTable[pos].quant>1 then
			lootTable[pos].itembutton:SetText(lootTable[pos].quant-lootTable[pos].prog+1)
		end
	end
	FLAwardFrame:SetHeight(30+(lootcount)*40)
end

function fld:CreateRollListButton(pos)
	local b = CreateFrame("button", "RollListButton"..pos, FLRollersList)
	pos = pos - 2 --since winning roll shows in main frame, not this one
	pos = -pos*16-3
	b:SetSize(190, 20)
	b:SetPoint("TOP", FLRollersList, "TOP", 3, pos)
	b:SetNormalFontObject("GameFontHighlightSmallLeft")
	b:SetHighlightFontObject("GameFontNormalSmallLeft")
	b:SetHighlightTexture("Interface\Buttons\UI-Listbox-Highlight2")
	table.insert(lootlistbuttons, b)
end

function fld:ShowRollersList(pos)
	fld:HideRollersList()
	if lootTable[pos].rolls[2] then
		local count = 0
		for i, rolltable in ipairs(lootTable[pos].rolls) do
			if i > 1 then
			   if not lootlistbuttons[i] then
				  fld:CreateRollListButton(i)
			   end
			   lootlistbuttons[i]:SetText(i..". "..rolltable.rollstr)
			   lootlistbuttons[i]:SetScript("OnClick", function(self) 
					fld:AwardPressed(pos, rolltable.player, rolltable.rolltype) 
					end)
			   lootlistbuttons[i]:Show()
			   count = count+1
			end
		end
		FLRollersList:SetHeight(count*16+12)
		FLRollersList:SetPoint("TOPLEFT", lootTable[pos].winnerbutton, "TOPRIGHT", 10, 3)
		FLRollersList:Show()
	end
end

function fld:HideRollersList()
	for i, button in ipairs(lootlistbuttons) do
		if i>1 then
			button:Hide()
		end
	end
	FLRollersList:Hide()
end

function fld:AwardPressed(pos, player, rolltype)
	fld:HideRollersList()	
	local val1, val2
	if rolltype=="n" then
		val1, val2 = flsys:GetValue(lootTable[pos].ilvl, lootTable[pos].itemid, lootTable[pos].equipLoc)
	else
		val1=0
	end
	if val2 then 
		val1 = val1.." or "..val2
	end
	local dialog = StaticPopup_Show("CONFIRM_MASTERLOOT", lootTable[pos].link, player, {["value"] = val1, ["rolltype"] = rolltype})
	if dialog then
		dialog.item = pos
		dialog.player = player
	end
end

function fld:AwardLoot(pos, player, value, rolltype)
	local prog = lootTable[pos].prog
	local index = "index"..prog
	local playerindex--have to find their index, diff for each piece of loot
	for p=1, GetNumRaidMembers() do
		if GetMasterLootCandidate(p)==player then
			playerindex = p
		end
	end
	if not GetLootSlotLink(lootTable[pos][index]) then
		StaticPopup_Show("WHEREISLOOT", lootTable[pos].link)
	elseif not playerindex then --not candidate
		flsys:Print(player.." is not a master loot candidate for "..lootTable[pos].link) --FIX should be popup
	else
		local announcemsg = lootTable[pos].link.." - "
		if player==lootTable[pos].rolls[1].player then
			-- if lootTable[pos].subannounce then
				-- flsys:Print(lootTable[pos].subannounce) --SendChatMessage(msg, "RAID", nil)
			-- end
			announcemsg = announcemsg..lootTable[pos].rolls[1].rollstr
		else
			announcemsg = announcemsg..player
		end
		SendChatMessage(announcemsg, "RAID", nil)
		GiveMasterLoot(lootTable[pos][index], playerindex) --TEST
		flsys:debug(3, "AWARD", "Awarded "..lootTable[pos].link.." to "..player)
		if lootTable[pos].prog == lootTable[pos].quant then
			lootTable[pos].winnerbutton:Hide()
		else
			table.remove(lootTable[pos].rolls, 1)
		end
		lootTable[pos].prog = lootTable[pos].prog+1
		flsys:OnLootAwarded(player, lootTable[pos].link, lootTable[pos].itemid, value)
		lootdone = lootdone + 1
		FLScanningTooltip:ClearLines() 
		if lootdone==lootcount then
			fld:EndAwarding()
		else
			fld:SortRolls()
		end
	end	
end

function fld:EndAwardingClicked()
	StaticPopup_Show("fldL_CONFIRM_ENDAWARD")
end

function fld:EndAwarding()
	FLScanningTooltip:ClearLines() 
	flsys:debug(1, "AWARD", "ending awarding")
	for pos, ltable in ipairs(lootTable) do
		lootTable[pos].itembutton:Hide()
		lootTable[pos].winnerbutton:Hide()
		lootTable[pos].done = false
		fld:ClearItem(pos)
	end
	for name, nt in pairs(roster) do
		nt.rollsdone = 0
	end
	rollsrec = 0
	FLProgressFrame:Hide()
	lootdone = 0
	lootcount = 0
	FLAwardFrame:Hide()
end

--CLEAR
function fld:ClearItem(pos)
  flsys:debug(2, "AWARD", "clearing item "..pos)
  lootTable[pos]["name"] = nil
  lootTable[pos]["link"] = nil
  lootTable[pos]["index"] = nil
  lootTable[pos]["needcount"] = 0
	lootTable[pos].prog = 1
	lootTable[pos].quant = 1
  lootTable[pos]["sub"] = nil
  lootTable[pos]["subroll"] = nil
  lootTable[pos]["subannounce"] = nil
  lootTable[pos]["rollopts"] = nil
  lootTable[pos]["rolls"]={} --TRASH
  lootTable[pos]["subs"]={}
end

--UTILITY
function fld:LinktoID(itemlink)
	local itemid = string.match(itemlink, "item:(%d+)")
	return itemid
end

function fld:IsBoE(link) --adapted from LibItemUtils-1.0 (EPGP)
	FLScanningTooltip:SetHyperlink(link)
	local text = FLScanningTooltipTextLeft2:GetText()
	FLScanningTooltip:ClearLines() 
	if text then
		if text==ITEM_BIND_ON_EQUIP then
			flsys:debug(3, link.." is BoE")
			return true
		else
			return false
		end
	end
end

function fld:IsMount(link)
	FLScanningTooltip:SetHyperlink(link)
	local three = FLScanningTooltipTextLeft3:GetText()
	local four = FLScanningTooltipTextLeft4:GetText()
	if (three and three=="Mount") or (four and four=="Mount") then
		flsys:debug(3, link.." is mount")
		return true
	else
		return false
	end
end

--PROCESS INC ADDON MSGS
function fld:CHAT_MSG_ADDON(event, prefix, message, channel, sender)
	if (prefix == "flamingloot") then
		local colon = strfind(message,":")
		local command = strsub(message,1, colon - 1)
		local param = strsub(message, colon + 1)
		if command == "roll" then
			fld:RollReceived(sender, param)
		end
	end
end

--CONFIRMATION
function fld:CheckSeller()
	StaticPopup_Show("SET_SELLER")
end

function fld:CheckSharder()
	StaticPopup_Show("SET_SHARDER")
end

StaticPopupDialogs["CONFIRM_MASTERLOOT"] = {
	text = "Give %s to %s?",
	button1 = ACCEPT,
	button2 = CANCEL,
	timeout = 0,
	whileDead = 1,  
	enterClicksFirstButton = true,
	hideOnEscape = 1,	
	hasEditBox = 1,
	maxLetters = 15,
	OnShow = function(self, data)
		self.editBox:SetText(tostring(data.value))
		self.editBox:HighlightText()
	end,
	OnAccept = function(self, data)
		local value = self.editBox:GetText()
		if not string.match(value, "^%d+$") then
			StaticPopup_Show("ENTERNUMBER")
		else
			value = tonumber(value)
			fld:AwardLoot(self.item, self.player, value, data.rolltype)
		end
	end
}

StaticPopupDialogs["ENTERNUMBER"] = {
	text = "Please enter a number.",
	button1 = ACCEPT,
	enterClicksFirstButton = true,
	timeout = 0,
	whileDead = 1, 
	hideOnEscape = 1,	
}

StaticPopupDialogs["fldL_CONFIRM_ENDAWARD"] = {
  text = "End awarding early?",
	button1 = ACCEPT,
	button2 = CANCEL,
	timeout = 0,
	whileDead = 1, 
	hideOnEscape = 1,	
	enterClicksFirstButton = true,	
	OnAccept = function(self)
		fld:EndAwarding()
	end
}

StaticPopupDialogs["SET_SELLER"] = {
	text = "Enter a name if you would like to assign someone in the raid to sell unneeded BoE items.",
	button1 = ACCEPT,
	button2 = CANCEL,
	timeout = 0,
	whileDead = 1,  
	hideOnEscape = 1,	
	hasEditBox = 1,
	maxLetters = 15,
	enterClicksFirstButton = true,
	OnAccept = function(self)
		local text = flsys:Cap(self.editBox:GetText())
		if roster[text] then
			fld.db.profile.seller = text
			flsys:Print(text.." set as the designated seller.")
		else
			flsys:Print("Name did not match a player in the raid. You can set a new name in the options menu.")
		end
	end
}

StaticPopupDialogs["SET_SHARDER"] = {
	text = "Enter a name if you would like to set a designated disenchanter for the raid.",
	button1 = ACCEPT,
	button2 = CANCEL,
	timeout = 0,
	enterClicksFirstButton = true,
	whileDead = 1,  
	hideOnEscape = 1,	
	hasEditBox = 1,
	maxLetters = 15,
	OnAccept = function(self)
		local text = flsys:Cap(self.editBox:GetText())
		if roster[text] then
			fld.db.profile.sharder = text
			flsys:Print(text.." set to disenchant unwanted items.")
		else
			flsys:Print("Name did not match a player in the raid. You can set a new name in the options menu.")
		end
		if not roster[fld.db.profile.seller] then
			fld:CheckSeller()
		end
	end,	
	OnCancel = function(self)	
		if not roster[fld.db.profile.seller] then
			fld:CheckSeller()
		end
	end
}

StaticPopupDialogs["WHEREISLOOT"] = {
  text = "%s not found.  Make sure you have the loot window opened.",
	button1 = ACCEPT,
	button2 = nil,
	sound = "igQuestLogAbandonQuest",
	timeout = 0,
	whileDead = 1, 
	hideOnEscape = 1,
	enterClicksFirstButton = true,
	OnAccept = function() end
}

StaticPopupDialogs["STARTLOOTING"] = {
  text = "Begin looting?",
	button1 = ACCEPT,
	button2 = CANCEL,
	timeout = 0,
	whileDead = 1, 
	hideOnEscape = 1,	
	enterClicksFirstButton = true,	
	OnAccept = function(self)
		fld:GetLootInfo()
	end
}

--TESTING

local testitems = {{["itemid"] = 58181}, {["itemid"] = 77197}, {["itemid"] = 78174}} --{["itemid"] = 72006}, {["itemid"] = 59444}} --71665 = alys mount, 58181 = fluid death, 68972 = boe str trink, 71361 = ranseur, 78859 = priest/pal/lock shoulder token 59444 str shield

function fld:FakeLootOpened()
	flsys:Print("fake loot")
	local announcemsg = "test loot: "
	wipe(lootCache)
	wipe(lootTable)
	for i=1, #testitems do
		local itemname, itemlink, rarity, iLevel, _, class, subtype, _, equipLoc, texture, _ = GetItemInfo(testitems[i].itemid)
		subtype = subtype or "no subtype"
		if rarity >= 1 then
			--passed checks
			local first = fld:FindCopy(itemlink)
			if first then
				lootTable[first].quant = lootTable[first].quant + 1
				lootTable[first]["index"..lootTable[first].quant] = i
			else
				lootcount = lootcount + 1
				if not lootTable[lootcount] then
					lootTable[lootcount] = {["rolls"]={}, ["needcount"]=0, ["texture"] = texture, ["subs"] = {}}
					fld:CreateAwardFrameSection(lootcount)
				end
				--store item info
				lootTable[lootcount].itemid = fld:LinktoID(itemlink)
				lootTable[lootcount].name = itemname
				lootTable[lootcount].equipLoc = equipLoc
				lootTable[lootcount].link = itemlink
				lootTable[lootcount].texture = texture
				lootTable[lootcount].ilvl = iLevel
				lootTable[lootcount].quant = 1
				lootTable[lootcount].index1 = i
				lootTable[lootcount].prog = 1
				lootCache[lootcount] = {["link"] = itemlink, ["rolls"] = {}} --cache	
				
				fld:TypeChecks(lootcount, itemname, itemlink, class, subtype)

				announcemsg = announcemsg..itemlink.." "
				if fld.db.profile.whispopts and lootTable[lootcount].rollopts then
					announcemsg = announcemsg.."("..lootTable[lootcount].rollopts..") "
				end
				if #announcemsg >170 then
					SendChatMessage(announcemsg, "RAID", nil)
					announcemsg = ""
				end
			end
		end
	end
		
	if lootcount>0 then
		lootmob = UnitName("target") or ""
		SendChatMessage(announcemsg, "RAID", nil)
		fld:StartLooting()
	end
end
--{["itemid"] = 77194}, {["itemid"] = 71998}, 

local itable = {
	[1] = {
		["rolls"] = {
			{["player"] = Rthurian, ["rolltype"] = g, ["roll"] = 56},
			{["player"] = Felmagi, ["rolltype"] = g, ["roll"] = 96},
			{["player"] = Manflower, ["rolltype"] = g, ["roll"] = 26},
			{["player"] = Airielle, ["rolltype"] = g, ["roll"] = 34},
			{["player"] = Kronborg, ["rolltype"] = g, ["roll"] = 18},
			{["player"] = Watwat, ["rolltype"] = g, ["roll"] = 62},
		},
	},
	[2] = {
		["rolls"] = {
			{["player"] = Rthurian, ["rolltype"] = g, ["roll"] = 16}, --1
			{["player"] = Felmagi, ["rolltype"] = g, ["roll"] = 29},
			{["player"] = Manflower, ["rolltype"] = g, ["roll"] = 04},
			{["player"] = Airielle, ["rolltype"] = g, ["roll"] = 89},
			{["player"] = Kronborg, ["rolltype"] = g, ["roll"] = 67},
			{["player"] = Watwat, ["rolltype"] = g, ["roll"] = 43},
		},
	},
}

function fld:FakeSort()
	table.sort(itable[1].rolls, function(rollA, rollB) return fld:SortIndivRolls(rollA, rollB) end) 
	for i, ro in ipairs(itable[1].rolls) do
		self:Print(i..ro.roll)
	--	itable[1].rolls[i].player.." rolled "..itable[1].rolls[i].roll)
	end
	table.sort(itable[2].rolls, function(rollA, rollB) return fld:SortIndivRolls(rollA, rollB) end) 
	for i, ro in ipairs(itable[2].rolls) do
		self:Print(i..ro.roll)
		--self:Print(itable[2].rolls[i].player.." rolled "..itable[2].rolls[i].roll)
	end
end
